package org.example.project.common.middleware.spi;

import org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator;
import org.example.project.common.middleware.spi.keygen.IdGenerator;
import org.example.project.common.util.SpringBeanHolder;

import java.util.Properties;

/**
 * @author wenxy
 * @date 2020/10/14
 */
public class RedisShardingKeyGenerator implements ShardingKeyGenerator {

    private static final String TYPE = "snowflake-redis";

    /**
     * 自增位数
     */
    private static final int INCR_BIT = 10;

    /**
     * 分片位数
     */
    private static final int SHARD_BIT = 7;
    Properties properties;
    /**
     * 分片id
     */
    private int shard = 0;

    /**
     * Generate key.
     * <p>
     * 使用46 bit来存放时间，精确到毫秒。
     * 使用7 bit来存放逻辑分片ID，最大分片ID是128
     * 使用10 bit来存放自增长ID，意味着每个节点，每毫秒最多可以生成1024个ID
     *
     * @return generated key
     */
    @Override
    public Comparable<?> generateKey() {
        long time = System.currentTimeMillis();
        IdGenerator idGenerator = SpringBeanHolder.getBean(IdGenerator.class);
        return time << (SHARD_BIT + INCR_BIT) | getShard() << INCR_BIT | idGenerator.generateId();
    }

    /**
     * Get algorithm type.
     *
     * @return type
     */
    @Override
    public String getType() {
        return TYPE;
    }

    /**
     * Get properties.
     *
     * @return properties of algorithm
     */
    @Override
    public Properties getProperties() {
        return properties;
    }

    /**
     * Set properties.
     *
     * @param properties properties of algorithm
     */
    @Override
    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public int getShard() {
        return shard;
    }

    public void setShard(int shard) {
        this.shard = shard;
    }
}
